home *** CD-ROM | disk | FTP | other *** search
/ NeXT Education Software Sampler 1992 Fall / NeXT Education Software Sampler 1992 Fall.iso / Programming / Source / HippoDraw / HippoDrawSrc1.1 / Hippo.subproj / InspectCut.m < prev    next >
Encoding:
Text File  |  1992-04-25  |  11.8 KB  |  475 lines

  1. /* InspectCut.m        by Mike Gravina        November 1991
  2.  * Controls the cuts on plots
  3.  *
  4.  * Copyright (C)  1991  The Board of Trustees of
  5.  * The Leland Stanford Junior University.  All Rights Reserved.
  6.  */ 
  7.  
  8. #import "InspectCut.h"
  9.  
  10. const char InspectCut_h_rcsid[] = INSPECTCUT_H_ID;
  11. const char InspectCut_m_rcsid[] = "$Id: InspectCut.m,v 1.44 1992/04/20 01:37:46 pfkeb Rel $";
  12.  
  13. #import <appkit/Application.h>
  14. #import <appkit/Button.h>
  15. #import <appkit/Panel.h>
  16. #import <appkit/Form.h>
  17. #import <appkit/NXBrowser.h>
  18. #import <appkit/NXBrowserCell.h>
  19. #import <appkit/Matrix.h>
  20. #import <objc/List.h>
  21. #include <string.h>
  22.  
  23. #import "FineSlider.h"
  24. #import "DrawDocument.h"
  25. #import "HDraw.h"
  26. #import "HGraphicView.h"
  27. #import "Plot.h"
  28. #import "NewInspector.h"
  29.  
  30. #define SCALE_FACTOR 5.0
  31. #define CUT_HI 0
  32. #define CUT_LO 1
  33.  
  34.  /*
  35.   * we want to KEEP what we select, but hippo wants to DELETE it...
  36.   * hence inverse cut types...
  37.   */
  38. char* cutTypeInverse[] = {"h_cut_gt", "h_cut_lt", "h_cut_outside",  "h_cut_in_incl"}; 
  39.     
  40.  
  41. @implementation InspectCut
  42. - initInspFor:aDraw
  43. {
  44.     [super initInspFor:aDraw];
  45.     
  46.     [NXApp loadNibSection:"InspectCut.nib" owner:self
  47.            withNames:NO fromZone:[self zone]];
  48.     
  49.     sliders[0] = cutVal1Slider;
  50.     sliders[1] = cutVal2Slider;
  51.     [ self setSliders:NO];
  52.     [sliders[CUT_LO] setScaleFactor:SCALE_FACTOR];
  53.     [sliders[CUT_HI] setScaleFactor:SCALE_FACTOR];
  54.     [self setShowAllState:NO];
  55.     
  56.     [theInspector addView:[contentBox contentView]
  57.              withName:"Cut Options" withSupervisor:self];
  58.     return self;
  59. }
  60.  
  61. - setSliders:(BOOL)flag
  62. {
  63.     float    xlp, xhp;
  64.     double    xl,  xh;
  65.     BOOL     val2Set;
  66.     
  67.     if ( !flag ) {
  68.         [sliders[0] setEnabled:NO];
  69.     [sliders[1] setEnabled:NO];
  70.     [cutValueForm setStringValue:"" at:CUT_LO];
  71.     [cutValueForm setStringValue:"" at:CUT_HI];
  72.     [cutValueForm  setEnabled:NO];
  73.         return self;
  74.     }
  75.     varlo = selectedTuple->nlow[parms.varIndex];
  76.     varhi = selectedTuple->nhigh[parms.varIndex];
  77.     [cutPlot getRangeForAxis:XAXIS low:&xlp high:&xhp];
  78.     xl = (varlo < xlp) ? xlp : varlo;
  79.     xh = (varhi > xhp) ? xhp : varhi;
  80.     [sliders[CUT_HI] setMinValue: xl];
  81.     [sliders[CUT_HI] setMaxValue: xh];
  82.     [sliders[CUT_LO] setMinValue: xl];
  83.     [sliders[CUT_LO] setMaxValue: xh];
  84.    
  85.     [cutValueForm setFloatValue:parms.cutValue1 at:CUT_LO];
  86.     [[cutValueForm cellAt: CUT_LO :0] setEnabled:YES];
  87.     [sliders[CUT_LO] setFloatValue:parms.cutValue1];
  88.     [sliders[CUT_LO] setEnabled:YES];
  89.     
  90.     if (parms.cutCode >= 2) {
  91.     val2Set = YES;
  92.     [cutValueForm setFloatValue:parms.cutValue2 at:CUT_HI];
  93.     [cutValueForm setEnabled:YES];
  94.     [sliders[CUT_HI] setFloatValue:parms.cutValue2];
  95.     [sliders[CUT_HI] setEnabled:YES];
  96.     [zpSwitch setEnabled:YES];
  97.     } else {
  98.     parms.cutValue2 = 0.0;
  99.     val2Set = NO;
  100.     [cutValueForm setStringValue:"" at:CUT_HI];
  101.     [[cutValueForm cellAt: CUT_HI :0] setEnabled:NO];
  102.     [sliders[CUT_HI] setFloatValue:varlo];
  103.     [sliders[CUT_HI] setEnabled:NO];
  104.     [zpSwitch setEnabled:NO];
  105.     }
  106.     return self;
  107. }
  108.  
  109. - newValueInForm:sender
  110. {
  111.     parms.cutValue1 = [cutValueForm floatValueAt:CUT_LO];
  112.     if (parms.cutValue1 < varlo)
  113.     parms.cutValue1 = varlo;
  114.     if (parms.cutValue1 > varhi)
  115.     parms.cutValue1 = varhi;
  116.  
  117.     if (parms.cutCode >= 2) {
  118.     parms.cutValue2 = [cutValueForm floatValueAt:CUT_HI];
  119.     if (parms.cutValue2 < varlo)
  120.         parms.cutValue2 = varlo;
  121.     if (parms.cutValue2 > varhi)
  122.         parms.cutValue2 = varhi;
  123.     }
  124.     [cutPlot setCutParms:&parms];
  125.     [self setSliders:YES];
  126.     [self reDrawPlot:@selector(changeCutPlot:) inList :dependList];
  127.     return self;
  128. }
  129.  
  130. - newValueInSlider2:sender
  131. {
  132.     float newValue1, diff;
  133.     
  134.     newValue1 = [sliders[CUT_LO] floatValue];
  135.     if (newValue1 == parms.cutValue1) return self;
  136.     diff = newValue1 - parms.cutValue1;
  137.     parms.cutValue1 = newValue1;
  138.     [cutValueForm setFloatValue:parms.cutValue1 at:CUT_LO];
  139.  
  140.     if (parms.cutCode >= 2 && [zpSwitch state] == YES) {
  141.         parms.cutValue2 += diff;
  142.         [cutValueForm setFloatValue:parms.cutValue2 at:CUT_HI];
  143.         [sliders[CUT_HI] setFloatValue:parms.cutValue2];
  144.     }
  145.     [cutPlot setCutParms:&parms];
  146.     [self reDrawPlot: @selector(changeCutPlot:) inList:dependList];
  147.         return self;
  148. }
  149.  
  150. - newValueInSlider1:sender
  151. {
  152.     float newValue2, diff;
  153.     
  154.     newValue2 = [sliders[CUT_HI] floatValue];
  155.     if (newValue2 == parms.cutValue2) return self;
  156.     diff = newValue2 - parms.cutValue2;
  157.     parms.cutValue2 = newValue2;
  158.     [cutValueForm setFloatValue:parms.cutValue2 at:CUT_HI];
  159.  
  160.     if (parms.cutCode >= 2 && [zpSwitch state] == YES) {
  161.         parms.cutValue1 -= diff;
  162.         [cutValueForm setFloatValue:parms.cutValue1 at:CUT_LO];
  163.         [sliders[CUT_LO] setFloatValue:parms.cutValue1];
  164.     }
  165.     [cutPlot setCutParms:&parms];
  166.     [self reDrawPlot: @selector(changeCutPlot:) inList:dependList];
  167.         return self;
  168. }
  169. - initCutParms
  170. {
  171.     cutButton = [radio selectedRow];
  172.     parms.cutCode = cutButton;
  173.     parms.cutFunc = cutTypeInverse[cutButton];
  174.     parms.varIndex = [tpBrowserCells selectedRow];
  175.  /*
  176.   * set the cut parameters to 'no-cut' starting values 
  177.   */
  178.     varlo = selectedTuple->nlow[parms.varIndex];
  179.     varhi = selectedTuple->nhigh[parms.varIndex];
  180.  
  181.     switch (parms.cutCode) {
  182.     case 0:
  183.     parms.cutValue1 = varhi;
  184.     break;
  185.     case 1:
  186.     parms.cutValue1 = varlo;
  187.     break;
  188.     case 2:
  189.     parms.cutValue1 = varlo;
  190.     parms.cutValue2 = varhi;
  191.     break;
  192.     case 3:
  193.     parms.cutValue1 = (varhi + varlo) / 2.0;
  194.     parms.cutValue2 = (varhi + varlo) / 2.0;
  195.     break;
  196.     }
  197.     return self;
  198. }
  199. - newCut:sender
  200. {
  201.     int        no = 0, yes = 1;
  202.     
  203.     if (!selectedTuple) {
  204.         return self;
  205.     }
  206.     [self initCutParms];
  207.     cutPlot = [graphicView addPlotOfType:HISTOGRAM andSelect:NO];
  208.     [cutPlot setCutHistFlag:YES];
  209.     [cutPlot bindAxisX:&parms.varIndex];
  210.     [cutPlot setLogScaleX:&no];
  211.     [cutPlot setLogScaleY:&no];
  212.     [cutPlot setAutoScaleX:&yes];
  213.     [cutPlot setAutoScaleY:&yes];
  214.     [cutPlot setTitlesFlag:&yes];
  215.     [cutPlot setAxesFlag:&yes];
  216.     [graphicView graphicsPerformSingle:@selector(setCutParms:)
  217.                                   with:(id)&parms on:cutPlot];
  218.     [graphicView cacheGraphic:cutPlot];
  219.     [[[graphicView window] flushWindow] makeKeyWindow];
  220.     dependList = [cutPlot dependList];
  221.     [docCutList addObject:cutPlot];
  222.     [self setSliders:YES];
  223.     if ( selectedPlot ) {
  224.     [addButton performClick:self];
  225.     } else {
  226.         [self setShowAllState:YES];
  227.     [self updateView];
  228.     }
  229.     return self;
  230. }
  231.  
  232. - deleteCut:plot
  233. {
  234.     [docCutList removeObject:plot];
  235.     if ( selectedPlot == plot ) {
  236.        selectedPlot = nil;
  237.     }
  238.     [self setSliders:NO];
  239.     [self updateView];
  240.     return self;
  241. }
  242. - addCut:plot
  243. {
  244.     [docCutList addObject:plot];
  245.     return self;
  246. }
  247. - add:sender
  248. {
  249.     int        i;
  250.     
  251.     [graphicView graphicsPerform:@selector(addCutPlot:)
  252.                             with:cutPlot andDraw:YES];
  253.     [graphicView graphicsPerformNOP:cutPlot];
  254.     [[[graphicView window] flushWindow] makeKeyWindow];
  255.     [self setShowAllState:NO];
  256.     [ self updateView];
  257.     i = [cutList indexOf:cutPlot];
  258.     cutBrowserCells = [cutBrowser matrixInColumn:0];
  259.     [cutBrowserCells selectCellAt:i :0];
  260.     return self;
  261. }
  262. - remove:sender
  263. {
  264.     [self removeCut:cutPlot];
  265.     [self setShowAllState:NO];
  266.     [self updateView];
  267.     return self;
  268. }
  269. - replace:sender
  270. {
  271.     id        applyList;
  272.     
  273.     if ( !cutPlot ) {
  274.         return self;
  275.     }
  276.     applyList = [[cutPlot dependList] copy];
  277.     [self removeCut:cutPlot];
  278.     [self initCutParms];
  279.     [cutPlot setCutParms:&parms];
  280.     [cutPlot bindAxisX:&parms.varIndex];
  281.     [self setSliders:YES];
  282.     [self reDrawPlot:@selector(addCutPlot:) inList: applyList];
  283.     [applyList free];
  284.     [graphicView graphicsPerformNOP:cutPlot];
  285.     [[[graphicView window] flushWindow] makeKeyWindow];
  286.     return self;
  287. }
  288. - removeCut:plot
  289. {
  290.     id        drawList;
  291.     
  292.     drawList = [[cutPlot dependList] copy];
  293.     [self reDrawPlot:@selector(removeCutPlot:) inList:drawList];
  294.     [drawList free];
  295.     return self;
  296. }
  297. - reDrawPlot: (SEL) operation inList:aList
  298. {
  299.     [graphicView graphicsPerform:operation    /* redraw selected list */
  300.                             with:cutPlot
  301.              andDraw:YES
  302.               inList:aList];
  303.     [graphicView graphicsPerformNOP:cutPlot];
  304.  
  305.  /*
  306.   * flush window buffer to screen 
  307.   */
  308.     [[[graphicView window] flushWindow] makeKeyWindow];
  309.  
  310.     return self;
  311. }
  312. - showButton:sender
  313. {
  314.     if ( showAllState ) {
  315.         [self setShowAllState:NO];
  316.     } else {
  317.         [self setShowAllState:YES];
  318.     }
  319.     [self updateView];
  320.     return self;
  321. }
  322. /* Methods that update the view */
  323. - setShowAllState:(BOOL) state
  324. {
  325.     if ( state ) {
  326.     [cutBrowser setTitle:"Available Cuts" ofColumn:0];
  327.     [showAllButton setTitle:"Show selected"];
  328.     showAllState = YES;
  329.     } else {
  330.     [cutBrowser setTitle:"Cuts on Selected Plot" ofColumn:0];
  331.     [showAllButton setTitle:"Show All"];
  332.     showAllState = NO;
  333.     }
  334.     return self;
  335. }
  336. - updateView
  337. {
  338.     unsigned int    i;
  339.     
  340.     docCutList = [graphicView cutList];
  341.     if ( selectedPlot ) {
  342.     [self setTuple:[selectedPlot ntuple]];
  343.     }
  344.     if ( showAllState ) {
  345.         cutList = docCutList;
  346.     [cutBrowser reloadColumn:0];
  347.     } else {
  348.         if ( selectedPlot ) {
  349.         cutList = [selectedPlot cutList];
  350.         [cutBrowser reloadColumn:0];
  351.     } else {
  352.         if ( cutList != nil ) {
  353.             cutList = nil;
  354.         [cutBrowser reloadColumn:0];
  355.         }
  356.     }
  357.     }
  358.     if ( cutPlot ) {
  359.     cutBrowserCells = [cutBrowser matrixInColumn:0];
  360.         i = [cutList indexOf:cutPlot];
  361.     if ( i == NX_NOT_IN_LIST ) {
  362.         [cutBrowserCells selectCellAt:-1 :-1 ];
  363.     } else {
  364.         [cutBrowserCells selectCellAt:i :0];
  365.     }
  366.     } else {
  367.         if ( [cutList count] ) {
  368.         cutBrowserCells = [cutBrowser matrixInColumn:0];
  369.         [cutBrowserCells selectCellAt:0 :0];
  370.     }
  371.     }
  372.     [self selectCut:self];
  373.     return self;
  374. }
  375. - updateEmptySelection
  376. {
  377.     docCutList = [graphicView cutList];
  378.     if ( showAllState ) {
  379.         if ( cutList != docCutList ) {
  380.         cutList = docCutList;
  381.         [cutBrowser reloadColumn:0];
  382.     }
  383.     } else {
  384.         cutList = nil;
  385.     [cutBrowser reloadColumn:0];
  386.     }
  387.     [self selectCut:self];
  388.     return self;
  389. }
  390. - setTuple:(ntuple) atuple
  391. {
  392.     if (selectedTuple == atuple)
  393.     return self;
  394.     selectedTuple = atuple;
  395.     [tpBrowser reloadColumn:0];
  396.     tpBrowserCells = [tpBrowser matrixInColumn:0];
  397.     return self;
  398. }
  399. - selectCut:sender
  400. {
  401.     int        i;
  402.     
  403.     cutBrowserCells = [cutBrowser matrixInColumn:0];
  404.     if ( !cutBrowserCells || (i=[cutBrowserCells selectedRow]) < 0 ) {
  405.         cutPlot = nil;
  406.     dependList = nil;
  407.     [self setSliders:NO];
  408.     return self;
  409.     }
  410.     cutPlot = [cutList objectAt:i];
  411.     dependList = [cutPlot dependList];
  412.     [cutPlot getCutParms:&parms];
  413.     [self setSliders:YES];
  414.     return self;
  415. }
  416. - selectCutVar
  417. {
  418.     [cutPlot getCutParms:&parms];
  419.     [tpBrowserCells selectCellAt:parms.varIndex :0];
  420.     [tpBrowserCells scrollCellToVisible:parms.varIndex :0];
  421.     [radio selectCellAt:parms.cutCode :0];
  422.     [self setSliders:YES];
  423.     return self;
  424. }
  425. /* Delegate Methods for NXBrowsers */
  426. - (int) browser: sender fillMatrix: matrix inColumn: (int) column
  427. {
  428.     id                  cut, aCell;
  429.     int                 i, numRows, count;
  430.     char                cutText[80];
  431.  
  432.     char               *cutType[] = {"Less", "Greater", "Within", "Outside"};
  433.  
  434.     numRows = 0;
  435.     if (sender == tpBrowser) {
  436.         [matrix allowEmptySel:NO];
  437.     if ( !selectedTuple ) {
  438.         return numRows;
  439.     }
  440.     numRows = h_getNtDim(selectedTuple);
  441.     for (i = 0; i < numRows; i++) {
  442.         [matrix insertRowAt:i];
  443.         aCell = [matrix cellAt:i :0];
  444.         [aCell setStringValue:h_getNtLabel(selectedTuple, i)];
  445.         [aCell setLeaf:YES];
  446.         [aCell setLoaded:YES];
  447.     }
  448.     } else if (sender == cutBrowser) {
  449.     /*
  450.      * load up a cell for each cut 
  451.      */
  452.     count = [cutList count];
  453.     for (i = 0; i < count; i++) {
  454.         cut = [cutList objectAt:i];
  455.         [matrix insertRowAt:i];
  456.         aCell = [matrix cellAt:i :0];
  457.     /*
  458.      * get variable that cut refers to 
  459.      */
  460.         [cut getCutParms:&parms];
  461.         strcpy(cutText, h_getNtLabel(selectedTuple, parms.varIndex));
  462.         strcat(cutText, " ");
  463.     /*
  464.      * concat the function name 
  465.      */
  466.         [aCell setStringValue:strcat(cutText, cutType[parms.cutCode])];
  467.         [aCell setLeaf:YES];
  468.         [aCell setLoaded:YES];
  469.     }
  470.     numRows = i;
  471.     }
  472.     return numRows;
  473. }
  474. @end
  475.